<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:c="livcos.org/ns/cosmos"
  xmlns:u="livcos.org/ns/cosmos/update"
  xmlns:t="livcos.org/ns/cosmos/type"
  xmlns:job="livcos.org/ns/process/job"
  xmlns="livcos.org/ns/doc"
  xmlns:doc="livcos.org/ns/doc"
  exclude-result-prefixes="c t doc">

  <xsl:import href="../../style/base.xsl" />
  <xsl:import href="style/SimpleId.xsl" />
  
  <xsl:param name="objId"/>
  <xsl:param name="scope"/>
  <xsl:param name="id"/>
  <xsl:param name="path" select="'.'" />
  <xsl:param name="view"/>
	
	<xsl:variable name="integrityCheckObjId" select="'/livcos.org/web/editor/integrity'"/>

  <xsl:variable name="idPath">
    <xsl:choose>
      <xsl:when test="(normalize-space($id) = '') or ($id = $objId)">
        <!-- take the root entity -->
        <xsl:text>.</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:call-template name="idPath">
          <xsl:with-param name="id" select="normalize-space($id)" />
        </xsl:call-template>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:template match="/*">
    <u:context ref="{$objId}" scope="{$scope}">
      <u:context select="{$idPath}">
        <xsl:apply-templates select="c:request/parameter/*" />
      </u:context>
    </u:context>
    <job:transform def="{$integrityCheckObjId}">
      <job:param name="obj" value="{$objId}"/>
    </job:transform>
    <job:feed ref="{$view}" stream="response" base="job"/>
  </xsl:template>
  
	<xsl:template match="*">
	</xsl:template>
	
	<xsl:template match="@* | node()" mode="content" priority="-1">
		<xsl:copy><xsl:apply-templates select="@* | node()" mode="content"/></xsl:copy>
	</xsl:template>
	
	<xsl:template match="@id" mode="content">
	</xsl:template>
	
	<xsl:template match="text()" mode="content">
		<xsl:value-of select="." disable-output-escaping="yes"/>
	</xsl:template>
	
  <xsl:template match="*" mode="content">
    <xsl:apply-templates select="node()" mode="content"/>
  </xsl:template>
  
	<xsl:template match="doc:*" mode="content">
		<xsl:element name="{local-name(.)}">
			<xsl:if test="@id">
				<xsl:attribute name="id">
					<xsl:value-of select="if (normalize-space(@id) != '') then @id else '{new-id()}'"/>
				</xsl:attribute>
			</xsl:if>
			<xsl:apply-templates select="@* | node()" mode="content"/>
		</xsl:element>
	</xsl:template>
	
	<xsl:template match="span" mode="content">
    <xsl:variable name="tagName">
      <xsl:choose>
        <xsl:when test="@style = 'font-weight: bold;'">strong</xsl:when>
        <xsl:when test="@style = 'font-style: italic;'">em</xsl:when>
        <xsl:when test="@style = 'text-decoration: underline;'">u</xsl:when>
        <xsl:when test="@style = 'text-decoration: line-through;'">s</xsl:when>
      </xsl:choose>
    </xsl:variable>
  	<xsl:choose>
  		<xsl:when test="$tagName != ''">
  			<xsl:element name="{$tagName}">
  				<xsl:apply-templates select="node()" mode="content"/>
  			</xsl:element>
  		</xsl:when>
  		<xsl:otherwise>
 				<xsl:apply-templates select="node()" mode="content"/>
  		</xsl:otherwise>
  	</xsl:choose>
  </xsl:template>
  
  <xsl:template match="u | code | sup | sub" mode="content">
    <xsl:element name="{lower-case(local-name(.))}">
      <xsl:apply-templates select="node()" mode="content"/>
    </xsl:element>
  </xsl:template>
  
	<xsl:template match="br" mode="content">
		<xsl:variable name="p" 
			select="preceding-sibling::node() except preceding-sibling::br except preceding-sibling::p[not(node())]"/>
		<xsl:variable name="f" 
			select="following-sibling::node() except following-sibling::br except following-sibling::p[not(node())]"/>
		<xsl:if test="$p and $f">
			<br/>
		</xsl:if>
	</xsl:template>
	
	<xsl:template match="b | strong" mode="content">
    <strong>
      <xsl:apply-templates select="node()" mode="content"/>
    </strong>
  </xsl:template>
  
  <xsl:template match="i | em" mode="content">
    <em>
      <xsl:apply-templates select="node()" mode="content"/>
    </em>
  </xsl:template>
  
  <xsl:template match="s | strike" mode="content">
    <s>
      <xsl:apply-templates select="node()" mode="content"/>
    </s>
  </xsl:template>
  
	<xsl:template match="p" mode="content">
		<xsl:if test="normalize-space(.) != ''">
			<xsl:variable name="_id" select="if (normalize-space(@id) != '') then @id else '{new-id()}'"/>
			<paragraph id="{$_id}">
				<xsl:apply-templates select="node()" mode="content"/>
			</paragraph>
		</xsl:if>
	</xsl:template>
	
	<xsl:template match="h1 | h2 | h3 | h4 | h5 | h6" mode="content">
		<title><xsl:apply-templates select="node()" mode="content"/></title>
	</xsl:template>
	
	<xsl:template match="img" mode="content">
		<xsl:variable name="_id" select="if (normalize-space(@id) != '') then @id else '{new-id()}'"/>
		<image id="{$_id}" ref="{@src}">
			<xsl:apply-templates select="@alt" mode="content"/>
		</image>
	</xsl:template>
	
	<xsl:template match="@alt" mode="content">
		<label>
			<xsl:value-of select="."/>
		</label>
	</xsl:template>
	
	<xsl:template match="A | a" mode="content">
		<xsl:variable name="_id" select="if (normalize-space(@id) != '') then @id else '{new-id()}'"/>
		<xsl:variable name="firstDef"
			select="((normalize-space(@href) = '') or (normalize-space(@href) = '#')) and not(@id) and not(@name)"/>
		<xsl:variable name="containsCode" select="matches(., '[^\[\]]+\[[^\[\]]+\]$')"/>
		<xsl:choose>
			<xsl:when test="$firstDef and $containsCode">
				<xsl:variable name="tokens" select="tokenize(., '[\[\]]')"/>
				<xsl:choose>
					<xsl:when test="normalize-space($tokens[2]) != ''">
						<link id="{$_id}" ref="{$tokens[2]}">
							<xsl:value-of select="$tokens[1]"/>
						</link>
					</xsl:when>
					<xsl:otherwise>
						<xsl:apply-templates select="node()" mode="content"/>
					</xsl:otherwise>
				</xsl:choose>
			</xsl:when>
      <xsl:when test="normalize-space(@href) = ''">
        <xsl:apply-templates select="node()" mode="content"/>
      </xsl:when>
      <xsl:otherwise>
        <link id="{$_id}">
          <xsl:attribute name="ref">
            <xsl:choose>
              <xsl:when test="starts-with(@href, 'cosmos://')">
                <xsl:value-of select="substring-after(@href, 'cosmos://')"/>
              </xsl:when>
              <xsl:otherwise>
                <xsl:value-of select="@href"/>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:attribute>
          <xsl:apply-templates select="node()" mode="content"/>
        </link>
      </xsl:otherwise>
    </xsl:choose>
	</xsl:template>
	
	<xsl:template match="table" mode="content">
		<xsl:variable name="_id" select="if (normalize-space(@id) != '') then @id else '{new-id()}'"/>
		<table id="{$_id}">
			<xsl:if test="thead">
				<head>
					<xsl:apply-templates select="thead/tr" mode="content"/>
				</head>
			</xsl:if>
			<xsl:if test="tbody | tr">
				<body>
					<xsl:apply-templates select="tbody/tr | tr" mode="content"/>
				</body>
			</xsl:if>
		</table>
	</xsl:template>
	
	<xsl:template match="tr" mode="content">
		<xsl:variable name="_id" select="if (normalize-space(@id) != '') then @id else '{new-id()}'"/>
		<row id="{$_id}">
			<xsl:apply-templates select="*" mode="content"/>
		</row>
	</xsl:template>
	
	<xsl:template match="td | th" mode="content">
		<xsl:variable name="_id" select="if (normalize-space(@id) != '') then @id else '{new-id()}'"/>
		<cell id="{$_id}">
			<xsl:copy-of select="@rowspan | @colspan"/>
			<xsl:apply-templates select="node()" mode="content"/>
		</cell>
	</xsl:template>
	
	<xsl:template match="ul | ol" mode="content">
		<xsl:variable name="_id" select="if (normalize-space(@id) != '') then @id else '{new-id()}'"/>
		<list id="{$_id}">
			<xsl:apply-templates select="li" mode="content"/>
		</list>
	</xsl:template>
	
	<xsl:template match="li" mode="content">
		<xsl:variable name="_id" select="if (normalize-space(@id) != '') then @id else '{new-id()}'"/>
		<item id="{$_id}">
			<xsl:apply-templates select="node()" mode="content"/>
		</item>
	</xsl:template>
	
	<xsl:template match="insertElement">
    <u:insert select="{$path}" create-path="yes">
      <xsl:apply-templates select="../*[starts-with(name(.),'ns')]" mode="ns"/>
      <xsl:element name="{../content}" />
    </u:insert>
  </xsl:template>
  
  <xsl:template match="insertAttribute">
    <u:insert select="{$path}" create-path="yes">
      <xsl:apply-templates select="../*[starts-with(name(.),'ns')]" mode="ns"/>
      <u:attribute name="{../content}">-- value --</u:attribute>
    </u:insert>
  </xsl:template>
  
  <xsl:template match="insert">
    <u:insert select="{$path}" create-path="yes">
      <xsl:apply-templates select="../*[starts-with(name(.),'ns')]" mode="ns"/>
    	<xsl:call-template name="buildContent">
    		<xsl:with-param name="content" select="../content/node()"/>
    	</xsl:call-template>
    </u:insert>
  </xsl:template>
  
  <xsl:template match="insert[../tmplObjId]">
    <u:info>
      <template ref="{../tmplObjId}#{../tmplId}"/>
    </u:info>
    <u:insert select="{$path}" create-path="yes">
      <xsl:apply-templates select="../*[starts-with(name(.),'ns')]" mode="ns"/>
      <xsl:variable name="tmplId" select="../tmplId"/>
      <xsl:apply-templates select="document(concat(../tmplObjId,'.view'))/*//*[@id = $tmplId]/t:content/node()"
        mode="tmpl"/>
    </u:insert>
  </xsl:template>
  
  <xsl:template match="insert[../path = '@xmlns']" priority="1">
    <u:decl-namespace select="." prefix="prefix" uri="uri.namespace"/>
  </xsl:template>
  
  <xsl:template match="update">
    <xsl:for-each select="../group[path and not(starts-with(path, 'name('))]">
      <xsl:call-template name="update">
        <xsl:with-param name="path" select="path"/>
        <xsl:with-param name="content" select="content/node()"/>
        <xsl:with-param name="type" select="type"/>
      </xsl:call-template>
    </xsl:for-each>
    <xsl:for-each select="../group[starts-with(path, 'name(')]">
      <xsl:call-template name="update">
        <xsl:with-param name="path" select="path"/>
        <xsl:with-param name="content" select="content/node()"/>
        <xsl:with-param name="type" select="type"/>
      </xsl:call-template>
    </xsl:for-each>
    <xsl:if test="not(../group[path])">
      <xsl:call-template name="update">
        <xsl:with-param name="path" select="$path"/>
        <xsl:with-param name="content" select="../content/node()"/>
        <xsl:with-param name="type" select="../type"/>
      </xsl:call-template>
    </xsl:if>
  </xsl:template>
  
	<xsl:template name="update">
		<xsl:param name="path"/>
		<xsl:param name="content"/>
		<xsl:param name="type"/>
		<xsl:choose>
			<xsl:when test="contains($path, '@') and (string($content) = '')">
				<u:delete select="{$path}" />
			</xsl:when>
			<xsl:otherwise>
				<u:update select="{$path}" create-path="yes">
					<xsl:apply-templates select="../*[starts-with(name(.),'ns')]" mode="ns"/>
					<xsl:call-template name="buildContent">
						<xsl:with-param name="content" select="$content"/>
						<xsl:with-param name="type" select="$type"/>
					</xsl:call-template>
				</u:update>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
	
	<xsl:template name="buildContent">
		<xsl:param name="content"/>
		<xsl:param name="type"/>
		<xsl:choose>
			<xsl:when test="$type = 'plain'">
				<xsl:copy-of select="$content"/>
			</xsl:when>
			<xsl:otherwise>
				<xsl:variable name="groupedContent">
					<xsl:for-each-group select="$content" group-starting-with="h1 | h2 | h3 | h4 | h5 | h6">
						<xsl:choose>
							<xsl:when test="self::h1 | self::h2 | self::h3 | self::h4 | self::h5 | self::h6">
								<chapter>
									<xsl:for-each select="current-group()">
										<xsl:copy>
											<xsl:apply-templates select="@* | node()" mode="groupContent"/>
										</xsl:copy>
									</xsl:for-each>
								</chapter>
							</xsl:when>
							<xsl:otherwise>
								<xsl:for-each select="current-group()">
									<xsl:copy>
										<xsl:apply-templates select="@* | node()" mode="groupContent"/>
									</xsl:copy>
								</xsl:for-each>
							</xsl:otherwise>
						</xsl:choose>
					</xsl:for-each-group>
				</xsl:variable>
				<xsl:apply-templates select="$groupedContent" mode="content"/>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
	
	<xsl:template match="@* | node()" mode="groupContent">
		<xsl:copy>
			<xsl:apply-templates select="@* | node()" mode="#current"/>
		</xsl:copy>
	</xsl:template>
	
	<xsl:template match="*" mode="groupContent" priority="2">
		<xsl:copy>
			<xsl:apply-templates select="@*" mode="#current"/>
			<xsl:for-each-group select="node()" group-starting-with="h1 | h2 | h3 | h4 | h5 | h6">
			<xsl:choose>
				<xsl:when test="self::h1 | self::h2 | self::h3 | self::h4 | self::h5 | self::h6">
					<chapter>
						<xsl:for-each select="current-group()">
								<xsl:apply-templates select="." mode="#current"/>
						</xsl:for-each>
					</chapter>
				</xsl:when>
				<xsl:otherwise>
					<xsl:for-each select="current-group()">
							<xsl:apply-templates select="." mode="#current"/>
					</xsl:for-each>
				</xsl:otherwise>
			</xsl:choose>
		</xsl:for-each-group>
		</xsl:copy>
	</xsl:template>
	
	<xsl:template match="update[contains(../id, '@xmlns:')]">
		<u:decl-namespace select="." prefix="{substring-after(../id,'@xmlns:')}" uri=""/>
    <u:decl-namespace select="." prefix="{../group[path = '@prefix']/content}" uri="{../group[path = '.']/content}"/>
  </xsl:template>
  
  <xsl:template match="delete">
    <u:delete select="." />
  </xsl:template>
  
  <xsl:template match="delete[contains(../id, '@xmlns')]">
    <u:decl-namespace select="." prefix="{substring-after(../id,'@xmlns:')}" uri=""/>
  </xsl:template>
  
  <xsl:template match="clone">
    <u:info>
      <copy object="{$objId}">
        <xsl:choose>
          <xsl:when test="matches($id, '^[0-9]')">
            <xsl:attribute name="node"><xsl:value-of select="$id"/></xsl:attribute>
          </xsl:when>
          <xsl:otherwise>
            <xsl:attribute name="entity"><xsl:value-of select="$id"/></xsl:attribute>
          </xsl:otherwise>
        </xsl:choose>
      </copy>
    </u:info>
    <u:insert position="after" select=".">
      <xsl:choose>
        <xsl:when test="$livcos_version >= '0.3'">
          <u:copy-of select="."/>
        </xsl:when>
        <xsl:otherwise>
          <u:copy-of select="preceding-sibling::*[1]"/>
        </xsl:otherwise>
      </xsl:choose>
    </u:insert>
  </xsl:template>
  
  <xsl:template match="create">
    <xsl:variable name="e" select="document(concat($objId, '.content'))/*//*[@id = $id]"/>
    <u:insert position="after" select=".">
      <u:copy-of ref="/livcos.org/type/template/{namespace-uri($e)}/{local-name($e)}"
        select="*[1]/t:content/node()">
        <u:namespace prefix="t" uri="livcos.org/ns/cosmos/type"/>
      </u:copy-of>
    </u:insert>
  </xsl:template>
  
  <xsl:template match="rename">
    <xsl:for-each select="../group[path]">
      <u:rename select="{path}" name="{content}"/>
    </xsl:for-each>
    <xsl:if test="not(../group[path])">
      <u:rename select="{$path}" name="{../content}"/>
    </xsl:if>
  </xsl:template>
  
  <xsl:template match="*" mode="ns">
    <u:namespace prefix="{substring(name(),4)}" uri="{.}"/>
  </xsl:template>
  
  <xsl:template match="ns" mode="ns">
    <u:namespace uri="{.}"/>
  </xsl:template>
  
  <xsl:template match="node()" mode="tmpl">
    <xsl:copy-of select="."/>
  </xsl:template>
  
  <xsl:template match="t:attribute" mode="tmpl">
    <u:attribute name="{@name}"><xsl:value-of select="."/></u:attribute>
  </xsl:template>
  
</xsl:stylesheet>
